package com.uniflow.controller;

import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.User;
import com.uniflow.security.CustomUserDetails;
import com.uniflow.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;

/**
 * 用户管理控制器
 */
@RestController
@RequestMapping("/api/v1/users")
@Validated
@Api(tags = "用户管理")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    /**
     * 分页查询用户列表
     */
    @GetMapping
    @PreAuthorize("hasAuthority('user:read')")
    public Result<PageResult<User>> getUserList(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String orgId,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String keyword) {
        try {
            PageResult<User> result = userService.getUserList(pageNum, pageSize, orgId, status, keyword);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据ID查询用户详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('user:read')")
    public Result<User> getUserById(@PathVariable String id) {
        try {
            User user = userService.getUserWithRoles(id);
            if (user == null) {
                return Result.error(ResultCode.USER_NOT_FOUND);
            }
            return Result.success(user);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 创建用户
     */
    @PostMapping
    @PreAuthorize("hasAuthority('user:write')")
    public Result<User> createUser(@Valid @RequestBody CreateUserRequest request) {
        try {
            User user = new User();
            user.setUsername(request.getUsername());
            user.setEmail(request.getEmail());
            user.setPasswordHash(request.getPassword());
            user.setDisplayName(request.getDisplayName());
            user.setPhone(request.getPhone());
            user.setOrgId(request.getOrgId());
            user.setStatus(request.getStatus() != null ? request.getStatus() : 1);
            
            User createdUser = userService.createUser(user);
            
            // 分配角色
            if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
                userService.assignRolesToUser(createdUser.getId(), request.getRoleIds());
            }
            
            return Result.success(createdUser);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新用户
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('user:write')")
    public Result<User> updateUser(@PathVariable String id, @Valid @RequestBody UpdateUserRequest request) {
        try {
            User user = new User();
            user.setId(id);
            user.setUsername(request.getUsername());
            user.setEmail(request.getEmail());
            user.setDisplayName(request.getDisplayName());
            user.setPhone(request.getPhone());
            user.setOrgId(request.getOrgId());
            user.setStatus(request.getStatus());
            
            // 如果提供了新密码，则更新密码
            if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) {
                user.setPasswordHash(request.getPassword());
            }
            
            User updatedUser = userService.updateUser(user);
            
            // 更新角色
            if (request.getRoleIds() != null) {
                userService.assignRolesToUser(id, request.getRoleIds());
            }
            
            return Result.success(updatedUser);
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 删除用户
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('user:write')")
    public Result<Void> deleteUser(@PathVariable String id) {
        try {
            // 检查是否为当前用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication.getPrincipal() instanceof CustomUserDetails) {
                CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
                if (userDetails.getId().equals(id)) {
                    return Result.error(ResultCode.OPERATION_NOT_ALLOWED, "不能删除当前登录用户");
                }
            }
            
            userService.deleteUser(id);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.DELETE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 批量删除用户
     */
    @DeleteMapping
    @PreAuthorize("hasAuthority('user:write')")
    public Result<Void> deleteUsers(@RequestBody @NotEmpty List<String> ids) {
        try {
            // 检查是否包含当前用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication.getPrincipal() instanceof CustomUserDetails) {
                CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
                if (ids.contains(userDetails.getId())) {
                    return Result.error(ResultCode.OPERATION_NOT_ALLOWED, "不能删除当前登录用户");
                }
            }
            
            userService.deleteUsers(ids);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.DELETE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 更新用户状态
     */
    @PatchMapping("/{id}/status")
    @PreAuthorize("hasAuthority('user:write')")
    public Result<Void> updateUserStatus(@PathVariable String id, @RequestBody UpdateStatusRequest request) {
        try {
            userService.updateUserStatus(id, request.getStatus());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 重置用户密码
     */
    @PatchMapping("/{id}/password")
    @PreAuthorize("hasAuthority('user:write')")
    public Result<Void> resetUserPassword(@PathVariable String id, @RequestBody ResetPasswordRequest request) {
        try {
            userService.resetUserPassword(id, request.getNewPassword());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 为用户分配角色
     */
    @PutMapping("/{id}/roles")
    @PreAuthorize("hasAuthority('user:write')")
    public Result<Void> assignRoles(@PathVariable String id, @RequestBody AssignRolesRequest request) {
        try {
            userService.assignRolesToUser(id, request.getRoleIds());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 根据组织ID查询用户列表
     */
    @GetMapping("/by-org/{orgId}")
    @PreAuthorize("hasAuthority('user:read')")
    public Result<List<User>> getUsersByOrgId(@PathVariable String orgId) {
        try {
            List<User> users = userService.getUsersByOrgId(orgId);
            return Result.success(users);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据角色ID查询用户列表
     */
    @GetMapping("/by-role/{roleId}")
    @PreAuthorize("hasAuthority('user:read')")
    public Result<List<User>> getUsersByRoleId(@PathVariable String roleId) {
        try {
            List<User> users = userService.getUsersByRoleId(roleId);
            return Result.success(users);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查用户名是否可用
     */
    @GetMapping("/check-username")
    public Result<Boolean> checkUsername(@RequestParam String username, @RequestParam(required = false) String excludeId) {
        try {
            boolean available = userService.isUsernameAvailable(username, excludeId);
            return Result.success(available);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查邮箱是否可用
     */
    @GetMapping("/check-email")
    public Result<Boolean> checkEmail(@RequestParam String email, @RequestParam(required = false) String excludeId) {
        try {
            boolean available = userService.isEmailAvailable(email, excludeId);
            return Result.success(available);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 获取用户统计信息
     */
    @GetMapping("/statistics")
    @PreAuthorize("hasAuthority('user:read')")
    public Result<Map<String, Object>> getUserStatistics() {
        try {
            Map<String, Object> statistics = userService.getUserStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    // 内部类：请求对象
    
    public static class CreateUserRequest {
        @NotBlank(message = "用户名不能为空")
        private String username;
        
        @NotBlank(message = "邮箱不能为空")
        private String email;
        
        @NotBlank(message = "密码不能为空")
        private String password;
        
        @NotBlank(message = "显示名称不能为空")
        private String displayName;
        
        private String phone;
        private String orgId;
        private Integer status;
        private List<String> roleIds;
        
        // getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDisplayName() { return displayName; }
        public void setDisplayName(String displayName) { this.displayName = displayName; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getOrgId() { return orgId; }
        public void setOrgId(String orgId) { this.orgId = orgId; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        public List<String> getRoleIds() { return roleIds; }
        public void setRoleIds(List<String> roleIds) { this.roleIds = roleIds; }
    }
    
    public static class UpdateUserRequest {
        private String username;
        private String email;
        private String password;
        private String displayName;
        private String phone;
        private String orgId;
        private Integer status;
        private List<String> roleIds;
        
        // getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDisplayName() { return displayName; }
        public void setDisplayName(String displayName) { this.displayName = displayName; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getOrgId() { return orgId; }
        public void setOrgId(String orgId) { this.orgId = orgId; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        public List<String> getRoleIds() { return roleIds; }
        public void setRoleIds(List<String> roleIds) { this.roleIds = roleIds; }
    }
    
    public static class UpdateStatusRequest {
        private Integer status;
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class ResetPasswordRequest {
        @NotBlank(message = "新密码不能为空")
        private String newPassword;
        
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }
    
    public static class AssignRolesRequest {
        private List<String> roleIds;
        
        public List<String> getRoleIds() { return roleIds; }
        public void setRoleIds(List<String> roleIds) { this.roleIds = roleIds; }
    }
}